﻿using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PasteLoggerBoard.redismodel;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;

namespace PasteLoggerBoard.usermodels
{
    /// <summary>
    /// 权限列表
    ///</summary>
    [TypeFilter(typeof(RoleAttribute), Arguments = new object[] { "data", "add" })]
    public class RoleInfoAppService : PasteLoggerBoardAppService
    {

        //private readonly IRepository<RoleInfo, int> _repository;


        private readonly IPasteLoggerBoardDbContext _dbContext;

        private readonly IAppCache _cache;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbContext"></param>
        /// <param name="cache"></param>
        public RoleInfoAppService(IPasteLoggerBoardDbContext dbContext, IAppCache cache)
        {

            _dbContext = dbContext;
            _cache = cache;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="page"></param>
        /// <param name="size"></param>
        /// <param name="groupid"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<PagedResultDto<RoleInfoListDto>> GetListAsync(int page = 1, int size = 20, int groupid = 0)
        {

            var query = _dbContext.RoleInfo.Where(t => 1 == 1).AsNoTracking().OrderBy(xy => xy.FatherId).ThenBy(x => x.Level);
            var pagedResultDto = new PagedResultDto<RoleInfoListDto>();
            pagedResultDto.TotalCount = await query.CountAsync();
            var userList = await query.Page(page, size).ToListAsync();
            var temList = ObjectMapper.Map<List<RoleInfo>, List<RoleInfoListDto>>(userList);

            if (groupid > 0)
            {
                foreach (var item in temList)
                {
                    item.IsEnable = false;
                }

                var binds = await _dbContext.GradeRole.Where(x => x.GradeId == groupid).AsNoTracking().ToListAsync();
                if (binds != null && binds.Count > 0)
                {
                    var roleids = binds.Select(x => x.RoleId).ToList();
                    var hitroles = temList.Where(x => roleids.Contains(x.Id)).ToList();
                    foreach (var item in hitroles)
                    {
                        item.IsEnable = true;
                    }
                }

            }
            pagedResultDto.Items = temList;

            return pagedResultDto;
        }

        /// <summary>
        /// 更新绑定
        /// </summary>
        /// <param name="groupid"></param>
        /// <param name="roleid"></param>
        /// <param name="state"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<int> UpdateBindRole(int groupid, int roleid, bool state)
        {
            var grade = _dbContext.GradeInfo.Where(x => x.Id == groupid).AsNoTracking().FirstOrDefault();

            var boolupdated = false;
            if (grade != null && grade != default)
            {
                if (state)
                {
                    var find = await _dbContext.GradeRole.Where(x => x.GradeId == groupid && x.RoleId == roleid).AsNoTracking().FirstOrDefaultAsync();
                    if (find == null || find == default)
                    {
                        boolupdated = true;
                        var one = new GradeRole();
                        one.GradeId = groupid;
                        one.RoleId = roleid;
                        _dbContext.Add(one);
                        await _dbContext.SaveChangesAsync();
                    }
                }
                else
                {
                    var find = await _dbContext.GradeRole.Where(x => x.GradeId == groupid && x.RoleId == roleid).FirstOrDefaultAsync();
                    if (find != null && find != default)
                    {
                        _dbContext.Remove(find);
                        await _dbContext.SaveChangesAsync();
                        boolupdated = true;
                    }
                }
            }
            if (boolupdated)
            {
                await _cache.DeleteAsync(string.Format(PublicString.CacheGradeInfoHead, grade.Name));
            }
            return 1;
        }

        /// <summary>
        /// 根据ID获取单项权限列表
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public RoleInfoDto GetByIdAsync(int id)
        {
            var query = _dbContext.RoleInfo.Where(t => t.Id == id)
                .FirstOrDefault();
            var temList = ObjectMapper.Map<RoleInfo, RoleInfoDto>(query);
            return temList;
        }

        /// <summary>
        /// 根据ID获取待更新单项信息权限列表
        ///</summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet]
        public RoleInfoUpdateDto GetInfoForUpdateAsync(int id)
        {
            var query = _dbContext.RoleInfo.Where(t => t.Id == id)
                .FirstOrDefault();
            var temList = ObjectMapper.Map<RoleInfo, RoleInfoUpdateDto>(query);
            return temList;
        }


        /// <summary>
        /// 添加一个权限列表
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<RoleInfoDto> CreateItemAsync(RoleInfoAddDto input)
        {
            //做排重处理
            var find = _dbContext.RoleInfo.Where(x => x.Model == input.Model && x.Name == input.Name).Any();
            if (find)
            {
                throw new PasteLoggerBoardException("已经存在这样的权限，无法重复添加");
            }

            var newu = ObjectMapper.Map<RoleInfoAddDto, RoleInfo>(input);
            newu.IsEnable = true;//添加自定义
            //var updated = await _repository.InsertAsync(newu, true);

            if (input.FatherId != 0)
            {
                var father = _dbContext.RoleInfo.Where(x => x.Id == input.FatherId).AsNoTracking().FirstOrDefault();
                if (father != null && father != default)
                {
                    newu.Level = father.Level + 1;
                }
                else
                {
                    newu.FatherId = 0;
                    newu.Level = 0;
                }
            }

            _dbContext.Add(newu);
            await _dbContext.SaveChangesAsync();
            var backinfo = ObjectMapper.Map<RoleInfo, RoleInfoDto>(newu);
            return backinfo;
        }
        /// <summary>
        /// 更新一个权限列表
        ///</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<RoleInfoDto> UpdateItemAsync(RoleInfoUpdateDto input)
        {

            var info = await _dbContext.RoleInfo.Where(x => x.Id == input.Id).FirstOrDefaultAsync();
            if (info == null || info == default)
            {
                throw new PasteLoggerBoardException("需要查询的信息不存在", "404");
            }

            if (input.FatherId != info.FatherId)
            {
                //更换父级了，有多少层嵌套？
                var father = _dbContext.RoleInfo.Where(x => x.Id == input.FatherId).AsNoTracking().FirstOrDefault();
                if (father != null && father != default)
                {
                    info.Level = father.Level + 1;
                }
                else
                {
                    info.FatherId = 0;
                    info.Level = 0;
                }
            }

            ObjectMapper.Map<RoleInfoUpdateDto, RoleInfo>(input, info);
            var backinfo = ObjectMapper.Map<RoleInfo, RoleInfoDto>(info);
            await _dbContext.SaveChangesAsync();
            return backinfo;
        }

        ///// <summary>
        ///// 删除权限列表软删除
        /////</summary>
        ///// <param name="id"></param>
        ///// <returns></returns>
        //[HttpPost]
        //public async Task<int> DeleteItemById(int id)
        //{
        //    var aione = await _repository.GetAsync(xy => xy.Id == id);//.FirstOrDefault();
        //    if (aione != default)
        //    {
        //        //await _repository.DeleteAsync(aione);
        //    }
        //    return 1;
        //}

    }
}
